{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import re\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import os\n",
    "%matplotlib inline\n",
    "# with serifs -> looks less out of place when used in latex files\n",
    "# plt.rcParams[\"font.family\"] = \"serif\"\n",
    "write_pdf = False\n",
    "# without serifs -> better for general viewing or for powerpoint\n",
    "plt.rcParams[\"font.family\"] = \"sans-serif\"\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "experiment_header_regex = re.compile(r\"Experiment: [a-z|_]+ [a-z]+$\")\n",
    "header_regex = re.compile(r\"Experiment: (.*) num_narrow_bursts: (\\d+) \" + \\\n",
    "    r\"num_wide_bursts: (\\d+) wide_burst_length: (\\d+)\")\n",
    "data_regex = re.compile(r\"(Old router|VC router ): \\[latency \\+- std, BW \\+- std\\]: \" + \\\n",
    "    r\"narrow: \\[(\\d+\\.\\d+) \\+- (\\d+\\.\\d+), (\\d+\\.\\d+) \\+- (\\d+\\.\\d+)\\], \" + \\\n",
    "    r\"wide: \\[(\\d+\\.\\d+) \\+- (\\d+\\.\\d+), (\\d+\\.\\d+) \\+- (\\d+\\.\\d+)\\]\")\n",
    "traffic_types_ordered = ['random read', 'random write', 'bit_complement read', 'bit_complement write', 'bit_reverse read', 'bit_reverse write', 'bit_rotation read', 'bit_rotation write', 'shuffle read', 'shuffle write', 'transpose read', 'transpose write', 'neighbor read', 'neighbor write', 'tornado read', 'tornado write', 'onehop read', 'onehop write', 'single_dest_center read', 'single_dest_center write', 'single_dest_boundary read', 'single_dest_boundary write', 'hbm read', 'hbm write', 'average (geo mean)']\n",
    "\n",
    "def get_data(experiment_name):\n",
    "    traffic_types = []\n",
    "    parameter_combinations = []\n",
    "    traffic_type = 0\n",
    "    parameter_combination_index = 0\n",
    "    data_list = []\n",
    "    errors = 0\n",
    "    with open(os.getcwd() + f\"/util/output/dma_experiments_{experiment_name}.txt\", \"r\") as file:\n",
    "        for line in file:\n",
    "            line = line.strip()\n",
    "            if line == \"\":\n",
    "                continue\n",
    "            experiment_header_match = experiment_header_regex.match(line)\n",
    "            header_match = header_regex.match(line)\n",
    "            data_match = data_regex.match(line)\n",
    "            if experiment_header_match:\n",
    "                continue\n",
    "            elif header_match:\n",
    "                header_match = header_match.groups()\n",
    "                if not header_match[0] in traffic_types:\n",
    "                    traffic_types.append(header_match[0])\n",
    "                traffic_type = header_match[0]\n",
    "                if not (int(header_match[1]), int(header_match[2]), int(header_match[3])) in parameter_combinations:\n",
    "                    parameter_combinations.append((int(header_match[1]), int(header_match[2]), int(header_match[3])))\n",
    "                parameter_combination_index = parameter_combinations.index((int(header_match[1]), int(header_match[2]), int(header_match[3])))\n",
    "            elif data_match:\n",
    "                data_match = data_match.groups()\n",
    "                data_list.append((traffic_type, parameter_combination_index, data_match[0], data_match[1], data_match[2], data_match[3], data_match[4], data_match[5], data_match[6], data_match[7], data_match[8]))\n",
    "            else:\n",
    "                print(\"Error: line not matched: \", line)\n",
    "                errors+=1\n",
    "                if(errors > 5): break\n",
    "    traffic_types.append(\"average (geo mean)\")\n",
    "    parameter_combinations.append(\"average (geo mean)\")\n",
    "\n",
    "    if(set(traffic_types) == set(traffic_types_ordered)): # set order if got all traffic types\n",
    "        traffic_types = traffic_types_ordered\n",
    "    data_array = np.ndarray((len(traffic_types), len(parameter_combinations), 2, 2), dtype=float)\n",
    "    data_array.fill(0.0)\n",
    "    for data in data_list:\n",
    "        assert(data[2] in (\"VC router \", \"Old router\"))\n",
    "        index = 0 if data[2] == \"Old router\" else 1\n",
    "        traffic_type_index = traffic_types.index(data[0])\n",
    "        # narrow\n",
    "        data_array[traffic_type_index][data[1]][index][0] += float(data[3]) # latency\n",
    "        # data_array[data[0]][data[1]][index][1] = float(data[4]) # latency std\n",
    "        # data_array[data[0]][data[1]][index][3] = float(data[5]) # bandwidth\n",
    "        # data_array[data[0]][data[1]][index][3] = float(data[6]) # bandwidth std\n",
    "        # wide\n",
    "        # data_array[data[0]][data[1]][index][4] = float(data[7]) # latency\n",
    "        # data_array[data[0]][data[1]][index][5] = float(data[8]) # latency std\n",
    "        data_array[traffic_type_index][data[1]][index][1] += float(data[9]) # bandwidth\n",
    "        # data_array[data[0]][data[1]][index][7] = float(data[10])# bandwidth std\n",
    "    if(\"random read\" in traffic_types):\n",
    "        data_array[traffic_types.index(\"random read\"),:,:,:] /= 5\n",
    "    if(\"random write\" in traffic_types):\n",
    "        data_array[traffic_types.index(\"random write\"),:,:,:] /= 5\n",
    "    data_array[-1,:,:,:] = np.prod(data_array[0:-1,:,:,:], axis=0)**(1.0/(len(traffic_types)-1))\n",
    "    data_array[:,-1,:,:] = np.prod(data_array[:,0:-1,:,:], axis=1)**(1.0/(len(parameter_combinations)-1))\n",
    "    return data_array, traffic_types, parameter_combinations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_experiment(data_array, traffic_types, parameter_combinations, experiment_name, bandwidth):\n",
    "    narrow_latency_comparison = 100*(data_array[:,:,1,0] - data_array[:,:,0,0]) / data_array[:,:,0,0]\n",
    "    wide_bw_comparison = 100*(data_array[:,:,1,1] - data_array[:,:,0,1]) / data_array[:,:,0,1]\n",
    "    plt.rcParams['figure.figsize'] = [10, 5]\n",
    "    fig, ax = plt.subplots()\n",
    "    # negate since color looks better if green is good\n",
    "    data = wide_bw_comparison if bandwidth else narrow_latency_comparison\n",
    "    ax.imshow(np.transpose(data if bandwidth else -data), cmap=\"RdYlGn\", vmin=-10, vmax=10)\n",
    "\n",
    "    # Show all ticks and label them with the respective list entries\n",
    "    traffic_types = list(map(lambda x: x.replace(\"_\", \" \"), traffic_types))\n",
    "    ax.set_xticks(np.arange(len(traffic_types)), labels=traffic_types)\n",
    "    ax.set_yticks(np.arange(len(parameter_combinations)), labels=parameter_combinations)\n",
    "\n",
    "    # Rotate the tick labels and set their alignment.\n",
    "    plt.setp(ax.get_xticklabels(), rotation=45, ha=\"right\",\n",
    "            rotation_mode=\"anchor\")\n",
    "\n",
    "    # Loop over data dimensions and create text annotations.\n",
    "    for i in range(len(parameter_combinations)):\n",
    "        for j in range(len(traffic_types)):\n",
    "            ax.text(j, i, f\"{data[j, i]:.1f}\",\n",
    "                ha=\"center\", va=\"center\", color=\"black\", fontsize=7)\n",
    "    explanation = \"Wide Bandwidth: $100*(BW_{vc}-BW_{old})\\ /\\ BW_{old}$\" if bandwidth \\\n",
    "      else \"Narrow Latency: $100*(Lat_{vc}-Lat_{old})\\ /\\ Lat_{old}$\"\n",
    "    if(experiment_name == \"SingleStageOgRouter\"):\n",
    "        explanation = \"Wide Bandwidth: $100*(BW_{single}-BW_{two})\\ /\\ BW_{two}$\" if bandwidth \\\n",
    "            else \"Narrow Latency: $100*(Lat_{single}-Lat_{two})\\ /\\ Lat_{two}$\"\n",
    "        ax.set_title(f\"Single vs two stage original router: {explanation}\")\n",
    "    else: ax.set_title(f\"{experiment_name}: {explanation}\")\n",
    "    fig.set_size_inches(8, 8)\n",
    "    bw_string = \"bw\" if bandwidth else \"lat\"\n",
    "    if write_pdf: plt.savefig(f\"util/plots/{experiment_name}_{bw_string}.pdf\", bbox_inches='tight')\n",
    "    plt.show()\n",
    "\n",
    "\n",
    "def analyze_experiment(experiment_name, bandwidth = False, slow = False):\n",
    "    experiment_addon = \"slowSlave\" if slow else \"\"\n",
    "    try:\n",
    "        data, traffic_types, parameter_combinations = get_data(experiment_addon + experiment_name)\n",
    "        plot_experiment(data, traffic_types, parameter_combinations, experiment_addon + experiment_name, bandwidth)\n",
    "    except FileNotFoundError:\n",
    "        print(f\"File not found: output/dma_experiments_{experiment_addon + experiment_name}.txt\")\n",
    "\n",
    "no_overflow_experiments = (\"VCd3NoOverflow\", \"VCd3NoOverflowVCL1\", \"VCd2NoOverflow\", \"VCd2NoOverflowVCL1\")\n",
    "single_vc_experiments = (\"SingleVCd3\",\"SingleVCd2\")\n",
    "vc_depth_experiments = (\"VCd2\", \"VCd3\", \"VCd2VCL1\", \"VCd3VCL1\")\n",
    "whd3_experiments = (\"VCd2Whd3\", \"VCd2Whd3VCL1\", \"VCd2Whd3NoOverflowFromWhVC\", \"VCd2Whd3VCL1NoOverflowFromWhVC\")\n",
    "no_credit_shortcut_experiments = (\"VCd2\", \"VCd2NoCreditShortcut\", \"VCd2NoOverflow\", \"VCd2NoOverflowNoCreditShortcut\",\"VCd3\",\"VCd3NoCreditShortcut\", \"VCd3NoOverflow\",\"VCd3NoOverflowNoCreditShortcut\")\n",
    "all_experiments = no_overflow_experiments + single_vc_experiments + vc_depth_experiments + whd3_experiments + no_credit_shortcut_experiments\n",
    "all_experiments = sorted(tuple(set(all_experiments)))\n",
    "# not part of all experiments\n",
    "single_stage_experiments = (\"SingleStageOgRouter\", \"SingleStageSingleVCd2\", \"SingleStageSingleVCd3\", \"SingleStageVCd2VCL1\", \"SingleStageVCd2VCL1NoOverflow\", \"SingleStageVCd2Whd3VCL1\", \"SingleStageVCd3VCL1\", \"SingleStageVCd3VCL1NoOverflow\" )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# slow = 0      # 0 for fast, 1 for slow slave\n",
    "# bandwidth = 1 # 0 for latency, 1 for bandwidth\n",
    "# for experiment in all_experiments:\n",
    "#      analyze_experiment(experiment, bandwidth, slow)\n",
    "for experiment in list(all_experiments) + list(single_stage_experiments):\n",
    "     analyze_experiment(experiment, 1, 0)\n",
    "     analyze_experiment(experiment, 0, 0)\n",
    "     analyze_experiment(experiment, 1, 1)\n",
    "     analyze_experiment(experiment, 0, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_parameter_combination(parameter_combination, experiment_names_og, parameter_combination_explanation=\"\", bandwidth=1, slow=0):\n",
    "  \"\"\"parameter combination can also be a list of parameter combinations, then it will plot geomean of them\"\"\"\n",
    "  experiment_names = list(experiment_names_og.copy())\n",
    "  experiment_addon = \"slowSlave\" if slow else \"\"\n",
    "  experiment_names= list(map(lambda x: experiment_addon + x, experiment_names))\n",
    "  relevant_data = []\n",
    "  traffic_types = None\n",
    "\n",
    "  #get data\n",
    "  for experiment_name_og in experiment_names_og:\n",
    "    experiment_name = experiment_addon + experiment_name_og\n",
    "    try:\n",
    "      data_exp, traffic_types_exp, parameter_combinations_exp = get_data(experiment_name)\n",
    "    except FileNotFoundError:\n",
    "        print(f\"File not found: output/dma_experiments_{experiment_name}.txt\")\n",
    "        experiment_names.remove(experiment_name)\n",
    "        continue\n",
    "    if traffic_types == None:\n",
    "      traffic_types = traffic_types_exp\n",
    "    else: # check same traffic types exist\n",
    "      if traffic_types != traffic_types_exp:\n",
    "        print(f\"Traffic types in {experiment_name} do not match previous experiments\")\n",
    "        experiment_names.remove(experiment_name)\n",
    "        continue\n",
    "    if type(parameter_combination) == list:\n",
    "      not_all_p_found = False\n",
    "      for p in parameter_combination:\n",
    "        if p not in parameter_combinations_exp:\n",
    "          print(f\"Parameter combination {p} not found in {experiment_name}\")\n",
    "          experiment_names.remove(experiment_name)\n",
    "          not_all_p_found = True\n",
    "          break\n",
    "      if not_all_p_found:\n",
    "        continue\n",
    "      relevant_data.append(\n",
    "        np.prod([data_exp[:,parameter_combinations_exp.index(p),:,:] for p in parameter_combination], axis=0)\n",
    "          **(1.0/len(parameter_combination)))\n",
    "        #  np.sum([data_exp[:,parameter_combinations_exp.index(p),:,:] for p in parameter_combination], axis=0))\n",
    "    else:\n",
    "      if parameter_combination in parameter_combinations_exp:\n",
    "        relevant_data.append(data_exp[:,parameter_combinations_exp.index(parameter_combination),:,:])\n",
    "      else:\n",
    "        print(f\"Parameter combination {parameter_combination} not found in {experiment_name}\")\n",
    "        experiment_names.remove(experiment_name)\n",
    "  relevant_data = np.transpose(np.array(relevant_data), axes=(1,0,2,3))\n",
    "  #plot data\n",
    "  narrow_latency_comparison = 100*(relevant_data[:,:,1,0] - relevant_data[:,:,0,0]) / relevant_data[:,:,0,0]\n",
    "  wide_bw_comparison = 100*(relevant_data[:,:,1,1] - relevant_data[:,:,0,1]) / relevant_data[:,:,0,1]\n",
    "  plt.rcParams['figure.figsize'] = [10, 5]\n",
    "  fig, ax = plt.subplots()\n",
    "  # negate since color looks better if green is good\n",
    "  data = wide_bw_comparison if bandwidth else narrow_latency_comparison\n",
    "  ax.imshow(np.transpose(data if bandwidth else -data), cmap=\"RdYlGn\", vmin=-10, vmax=10)\n",
    "  if \"SingleStageOgRouter\" in experiment_names:\n",
    "    experiment_names[experiment_names.index(\"SingleStageOgRouter\")] = \"Single vs two stage original router\"\n",
    "\n",
    "  # Show all ticks and label them with the respective list entries\n",
    "  traffic_types = list(map(lambda x: x.replace(\"_\", \" \"), traffic_types))\n",
    "  ax.set_xticks(np.arange(len(traffic_types)), labels=traffic_types)\n",
    "  ax.set_yticks(np.arange(len(experiment_names)), labels=experiment_names)\n",
    "\n",
    "  # Rotate the tick labels and set their alignment.\n",
    "  plt.setp(ax.get_xticklabels(), rotation=45, ha=\"right\",\n",
    "          rotation_mode=\"anchor\")\n",
    "\n",
    "  # Loop over data dimensions and create text annotations.\n",
    "  for i in range(len(experiment_names)):\n",
    "      for j in range(len(traffic_types)):\n",
    "          ax.text(j, i, f\"{data[j, i]:.1f}\",\n",
    "              ha=\"center\", va=\"center\", color=\"black\", fontsize=7)\n",
    "  explanation = \"Wide Bandwidth: $100*(bw_{vc}-bw_{old})\\ /\\ bw_{old}$\" if bandwidth \\\n",
    "      else \"Narrow Latency: $100*(Lat_{vc}-Lat_{old})\\ /\\ Lat_{old}$\"\n",
    "\n",
    "  ax.set_title(f\"{parameter_combination_explanation}: {explanation}\")\n",
    "  fig.set_size_inches(8, 8)\n",
    "  bw_string = \"bw\" if bandwidth else \"lat\"\n",
    "  if write_pdf: plt.savefig(f\"util/plots/{parameter_combination_explanation.lower().replace(',', '').replace(' ', '_')}_{bw_string}.pdf\", bbox_inches='tight')\n",
    "  plt.show()\n",
    "\n",
    "def plot_all_parameter_combinations(bandwidth = 1, slow = 0, single_stage=0):\n",
    "  all_parameter_combinations = ((4,4,1), (4,4,16), (4,16,1), (4,16,16), (16,16,4), (16,16,8), (16,16,16), (16,32,16), (16,64,16), (32,16,16), (64,16,16), (64,1,4), (64,4,4), (64,16,4), (1,64,4), (4,64,4), (16,64,4), (32,64,4))\n",
    "  slow_str = \"Slow Slave \" if slow else \"\"\n",
    "  for p in all_parameter_combinations:\n",
    "    parameter_combination_explanation = \"Low Load \" if p == (4,4,1) else \\\n",
    "    \"Low Load, Bursts \" if p == (4,4,16) else \"\"\n",
    "    parameter_combination_explanation += str(p)\n",
    "    if single_stage:\n",
    "      plot_parameter_combination(p, list(single_stage_experiments),slow_str + \"Single Stage \" + parameter_combination_explanation, bandwidth, slow)\n",
    "    else:\n",
    "      plot_parameter_combination(p, all_experiments,slow_str + parameter_combination_explanation, bandwidth, slow)\n",
    "\n",
    "def plot_geomean_of_high_load(bandwidth=1, slow=0, single_stage=0):\n",
    "  high_load_parameter_combinations =  list(((16,16,16), (16,32,16), (16,64,16), (32,16,16), (64,16,16)))\n",
    "  slow_str = \"Slow Slave \" if slow else \"\"\n",
    "\n",
    "  if single_stage:\n",
    "    plot_parameter_combination(high_load_parameter_combinations, list(single_stage_experiments), slow_str + \"Single Stage High Load\", bandwidth, slow)\n",
    "  else:\n",
    "    plot_parameter_combination(high_load_parameter_combinations, all_experiments, slow_str + \"High Load\", bandwidth, slow)\n",
    "\n",
    "def plot_geomean_of_all(bandwidth=1, slow=0, single_stage=0):\n",
    "  all_parameter_combinations = list(((4,4,1), (4,4,16), (4,16,1), (4,16,16), (16,16,4), (16,16,8), (16,16,16), (16,32,16), (16,64,16), (32,16,16), (64,16,16), (64,1,4), (64,4,4), (64,16,4), (1,64,4), (4,64,4), (16,64,4), (32,64,4)))\n",
    "  slow_str = \"Slow Slave \" if slow else \"\"\n",
    "  if single_stage:\n",
    "    plot_parameter_combination(all_parameter_combinations, list(single_stage_experiments), slow_str + \"Single Stage Geometric mean\", bandwidth, slow)\n",
    "  else:\n",
    "    plot_parameter_combination(all_parameter_combinations, all_experiments, slow_str + \"Geometric mean\", bandwidth, slow)\n",
    "\n",
    "\n",
    "plot_geomean_of_all(bandwidth=1, slow=0, single_stage=0)\n",
    "plot_geomean_of_all(bandwidth=0, slow=0, single_stage=0)\n",
    "plot_geomean_of_high_load(bandwidth=1, slow=0, single_stage=0)\n",
    "plot_geomean_of_high_load(bandwidth=0, slow=0, single_stage=0)\n",
    "plot_all_parameter_combinations(bandwidth=1,slow=0, single_stage=0)\n",
    "plot_all_parameter_combinations(bandwidth=0,slow=0, single_stage=0)\n",
    "# slow slave experiments\n",
    "plot_geomean_of_all(bandwidth=1, slow=1, single_stage=0)\n",
    "plot_geomean_of_all(bandwidth=0, slow=1, single_stage=0)\n",
    "plot_geomean_of_high_load(bandwidth=1, slow=1, single_stage=0)\n",
    "plot_geomean_of_high_load(bandwidth=0, slow=1, single_stage=0)\n",
    "plot_all_parameter_combinations(bandwidth=1,slow=1, single_stage=0)\n",
    "plot_all_parameter_combinations(bandwidth=0,slow=1, single_stage=0)\n",
    "# single stage\n",
    "plot_geomean_of_all(bandwidth=1, slow=0, single_stage=1)\n",
    "plot_geomean_of_all(bandwidth=0, slow=0, single_stage=1)\n",
    "plot_geomean_of_high_load(bandwidth=1, slow=0, single_stage=1)\n",
    "plot_geomean_of_high_load(bandwidth=0, slow=0, single_stage=1)\n",
    "plot_all_parameter_combinations(bandwidth=1, slow=0, single_stage=1)\n",
    "plot_all_parameter_combinations(bandwidth=0, slow=0, single_stage=1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_single_experiment_bar_plot(parameter_combination, routers,routers_legend, title, bounds=(0.9,1.1), bandwidth=1, slow=0):\n",
    "  experiment_addon = \"slowSlave\" if slow else \"\"\n",
    "  data_exp_list = []\n",
    "  for experiment in routers:\n",
    "    try:\n",
    "      data_exp, traffic_types, parameter_combinations = get_data(experiment_addon + experiment)\n",
    "      if parameter_combination not in parameter_combinations:\n",
    "        print(f\"Parameter combination {parameter_combination} not found in {experiment_addon + experiment}\")\n",
    "        continue\n",
    "      narrow_latency_comparison = data_exp[:,parameter_combinations.index(parameter_combination),1,0]/ data_exp[:,parameter_combinations.index(parameter_combination),0,0]\n",
    "      wide_bw_comparison = data_exp[:,parameter_combinations.index(parameter_combination),1,1]/ data_exp[:,parameter_combinations.index(parameter_combination),0,1]\n",
    "      data_exp = wide_bw_comparison if bandwidth else narrow_latency_comparison\n",
    "      data_exp_list.append(data_exp)\n",
    "    except FileNotFoundError:\n",
    "        print(f\"File not found: output/dma_experiments_{experiment_addon + experiment}.txt\")\n",
    "        continue\n",
    "  fig, ax = plt.subplots()\n",
    "  x = np.arange(len(traffic_types))\n",
    "\n",
    "  width = 1/(len(data_exp_list)+1)\n",
    "  for i, data_exp in enumerate(data_exp_list[::-1]):\n",
    "    ax.bar(x + (i - len(data_exp_list)/2)*width, data_exp_list[i] -0.8, width , label=routers_legend[i], bottom=0.8)\n",
    "\n",
    "  ax.set_ylabel('$BW_{vc}\\ /\\ BW_{old}$' if bandwidth else '$Lat_{vc}\\ /\\ Lat_{old}$')\n",
    "  ax.set_title(f'{title}')\n",
    "  ax.set_ylim(bounds[0],bounds[1])\n",
    "  ax.set_xticks(x)\n",
    "  traffic_types = map(lambda x: x.replace(\"_\", \" \"), traffic_types)\n",
    "  ax.set_xticklabels(traffic_types)\n",
    "  ax.yaxis.grid(True, linestyle='--', which='major',\n",
    "                   color='grey', alpha=.25)\n",
    "  plt.axhline(1, color='black', linewidth=0.5)\n",
    "    # Rotate the tick labels and set their alignment.\n",
    "  plt.setp(ax.get_xticklabels(), rotation=45, ha=\"right\",\n",
    "          rotation_mode=\"anchor\")\n",
    "  ax.legend()\n",
    "  fig.set_size_inches(10, 5)\n",
    "  plt.savefig(f\"util/plots/barplot_{routers}_{bandwidth}_{slow}.pdf\", bbox_inches='tight')\n",
    "  plt.show()\n",
    "\n",
    "# All plots are without hbm and single dest boundary\n",
    "plot_single_experiment_bar_plot((4,4,16), (\"VCd2\", \"VCd3\"),(\"Buffer depth 2\", \"Buffer depth 3\"), \"Low load with bursts: Normalized wide bandwidth: Different buffer depths\", bandwidth=1, slow=0)\n",
    "plot_single_experiment_bar_plot((4,4,16), (\"VCd2Whd3VCL1\", \"VCd3\"),(\"Buffer depth 2-3, local port optimized\", \"Buffer depth 3\"), \"Low load with bursts: Normalized wide bandwidth: Optimized router\", bandwidth=1, slow=0)\n",
    "plot_single_experiment_bar_plot((4,4,16), (\"SingleVCd2\", \"SingleVCd3\"),(\"Buffer depth 2, no VC\", \"Buffer depth 3, no VC\"), \"Low load with bursts: Normalized wide bandwidth: Different buffer depths without virtual channels\", bounds = (0.8,1.1), bandwidth=1, slow=0)\n",
    "plot_single_experiment_bar_plot((4,4,16), (\"VCd2\", \"VCd2NoCreditShortcut\"),(\"Buffer depth 2\", \"Low load with bursts: Buffer depth 2, no credit shortcut\"), \"Low load with bursts: Normalized wide bandwidth: Credit shortcut with buffer depth 2\", bandwidth=1, slow=0)\n",
    "plot_single_experiment_bar_plot((4,4,16), (\"VCd3\", \"VCd3NoCreditShortcut\"),(\"Buffer depth 3\", \"Buffer depth 3, no credit shortcut\"), \"Low load with bursts: Normalized wide bandwidth: Credit shortcut with buffer depth 3\", bandwidth=1, slow=0)\n",
    "plot_single_experiment_bar_plot((4,4,16), (\"SingleStageVCd2VCL1\", \"SingleStageVCd3VCL1\"),(\"Single Stage Buffer depth 2, optimized local port\", \"Single Stage Buffer depth 3, optimized local port\"), \"Low load with bursts: Normalized wide bandwidth: Single stage routers with different buffer depth\", bounds=(0.9, 1.2), bandwidth=1, slow=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "floo",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
